// 购物车组件
<template>
    <div class="buy-div" v-if="!noToken">
        <el-row>
            <el-col :span="4" :offset="16" class="buy-div-col">
                选中行价格总和: <span class="buy-div-col-price">{{ totalPrice }}</span> 元
            </el-col>
            <el-col :span="4" class="buy-div-col">
                <el-button class="buy-div-col-button" color="#FF4900" size="large" @click="toBuy" :disabled="loading || totalPrice == 0 || total == 0"
                    :loading="buLoading" v-loading.fullscreen.lock="fullscreenLoading"
                    element-loading-text="结算中。。。">结算</el-button>
            </el-col>
        </el-row>
    </div>
    <el-table ref="tableRef" :data="cartList" v-if="!noToken" border class="table-up"
        @selection-change="handleSelectionChange" v-loading="loading" element-loading-text="数据请求中。。。">
        <el-table-column type="selection" width="32" />
        <el-table-column label="商品详情">
            <template #default="scope">
                <el-row>
                    <el-col :span="6" class="table-row-col-img">
                        <el-image class="table-image" :src="scope.row.picture_urls[0]" :zoom-rate="1.2" :max-scale="7"
                            :min-scale="0.2" :preview-src-list="scope.row.picture_urls" preview-teleported
                            :initial-index="4" fit="cover" />
                    </el-col>
                    <el-col :span="18" class="table-row-col-info">
                        <el-row @click="toShowProductInfo(scope.row.id)">
                            <el-col :span="24" :title="scope.row.category" class="table-row-col-txt">
                                {{ scope.row.category }}
                            </el-col>
                            <el-col :span="24" :title="scope.row.title" class="table-row-col-txt">
                                {{ scope.row.name }}
                            </el-col>
                            <el-col :span="24" :title="scope.row.desc" class="table-row-col-txt text_desc">
                                {{ scope.row.desc }}
                            </el-col>
                        </el-row>
                    </el-col>
                </el-row>
            </template>
        </el-table-column>
        <el-table-column label="商品单价(元)" width="100">
            <template #default="scope">
                <div class="row-price">
                    ￥： {{ scope.row.price }}
                </div>
            </template>
        </el-table-column>/>
        <el-table-column label=" 商品数量（个/份）" width="120">
            <template #default="scope">
                X {{ scope.row.count }}
            </template>
        </el-table-column>/>
        <el-table-column label="操作" width="85">
            <template #default="scope">
                <el-button size="small" type="danger" :loading="deleteRowLoadingStatus.get(scope.row.id)"
                    @click="handleDelete(scope.row.id)">
                    删除
                </el-button>
            </template>
        </el-table-column>
    </el-table>
    <el-empty v-if="noToken" description="登陆后查看数据" style="width: 100%;" />
    <div class="el-card-pagination" v-if="!noToken && total > 0">
        <el-pagination background size="large" layout="prev, pager, next" :total="total" :page-size="pageSize"
            @current-change="handlePageChange" />
    </div>

</template>

<script setup lang="ts">
import { ElTable } from 'element-plus';
import { cc } from '@/api/typemapping';
import { useRouter } from 'vue-router';
import { HttpMethod } from '@/api/types';
import { ElMessage } from 'element-plus';
import { apiRequest } from '@/api/apiService';
import { ref, onMounted, reactive } from 'vue';
import { AuthService } from '@/api/authService';

const tableRef = ref();                                         // 表格对象
const cartList = ref();                                         // 响应数据
const noToken = ref(true);                                      // 未登录状态
const router = useRouter();                                     // 获取路由实例
const totalPrice = ref(0);                                      // 定义计算选中行某字段总和的响应式变量
const loading = ref(false);                                     // loading标识
const buLoading = ref(false);                                   // 按钮loading
const total = ref<number>(0);                                   // 总条目数
const pageSize = ref<number>(10);                               // 每页显示条目数
const currentPage = ref<number>(1);                             // 当前页码
const fullscreenLoading = ref(false);                           // 全页面loading
const selectedRows = ref<Commodity[]>([]);                      // 定义存储选中行数据的响应式变量
const deleteRowLoadingStatus = ref(new Map<number, boolean>()); // 删除状态map
const listParam = reactive({                                    // 列表请求参数
    keyword: '',
    page_number: 1,
    page_size: 10
});
const deleteRowParam = reactive({                               // 删行请求参数
    commodity_id: 0
});
const settlementParam = reactive<{ commodity_ids: number[] }>({ // 结算请求参数
    commodity_ids: []
});
interface Commodity {                                           // 商品对象 
    id: number;
    name: string;
    category: number;
    title: string;
    desc: string;
    price: number;
    count: number;
    picture_urls: string[];
}

// 初始化
onMounted(() => {
    // 判断是否登录
    if (AuthService.getToken() == '') {
        ElMessage({
            message: '请先登录后，查看购物车列表！',
            type: 'error',
        });
        total.value = 0;
        noToken.value = true;
    } else {
        noToken.value = false;
        refresh();
    }
});

// 删除操作
const handleDelete = async (id: number) => {
    deleteRowParam.commodity_id = id;
    deleteRowLoadingStatus.value.set(id, true);
    await deleteRow();
    refresh();
}

// 商品详情
const toShowProductInfo = (id: string) => {
    // 使用 router.push 方法跳转到指定的路由，并带上参数
    const pid = id;
    router.push({ name: 'productDetail', params: { id: pid } });
}

// 处理页码切换的事件
const handlePageChange = (page: number) => {
    currentPage.value = page;
    refresh();
};

// 数据刷新
const refresh = () => {
    loading.value = true;
    listParam.keyword = '';
    listParam.page_number = currentPage.value;
    listParam.page_size = pageSize.value;
    deleteRowLoadingStatus.value.forEach((value, key) => {
        deleteRowLoadingStatus.value.set(key, false);
    });
    clearSelectedTableInfo();
    getCartList();
}

// 处理选中行变化的方法
const handleSelectionChange = (val: Commodity[]) => {
    selectedRows.value = val;
    calculateTotalPrice();
};

// 计算选中行价格总和的方法
const calculateTotalPrice = () => {
    let sum = 0;
    selectedRows.value.forEach((row: Commodity) => {
        sum += row.price * row.count;
    });
    totalPrice.value = sum;
};

// 点击支付
const toBuy = async (id: number) => {
    settlementParam.commodity_ids = [];
    settlementParam.commodity_ids = selectedRows.value.map(row => row.id);
    buLoading.value = true;
    fullscreenLoading.value = true;
    await toSettlement();
    refresh();
}

// 清空选中项
const clearSelectedTableInfo = () => {
    if (tableRef?.value) {
        tableRef.value.clearSelection();
        totalPrice.value = 0;
    }
};

// 获取购物车列表请求
const getCartList = async () => {
    try {
        const url = '/cart/list';
        const customHeaders = { 'Authorization': AuthService.getToken() };
        const response = await apiRequest.request<any>(HttpMethod.POST, url, listParam, customHeaders);
        response.data.forEach((item: Commodity) => {
            if(!item.picture_urls){
                item.picture_urls = [];
            }
        });
        cartList.value = response.data;
        selectedRows.value.forEach((row: Commodity) => {
            deleteRowLoadingStatus.value.set(row.id, false);
        });
        total.value = response.total;
        loading.value = false;
    } catch (error) {
        console.log('request: /api/cart/list failed, error message: ', error);
        selectedRows.value.forEach((row: Commodity) => {
            deleteRowLoadingStatus.value.set(row.id, false);
        });
        loading.value = false;
    }
};

// 删除购物车行请求
const deleteRow = async () => {
    try {
        const url = '/cart/';
        const customHeaders = { 'Authorization': AuthService.getToken() };
        await apiRequest.request<any>(HttpMethod.DELETE, url, deleteRowParam, customHeaders);
        ElMessage({
            message: '删除成功',
            type: 'success',
        });
    } catch (error) {
        console.log(`request: /api/cart/?commodity_id=${deleteRowParam.commodity_id} failed, error message: ${error}`);
    }
};

// 发起结算请求
const toSettlement = async () => {
    try {
        const url = '/cart/pay';
        const customHeaders = { 'Authorization': AuthService.getToken() };
        await apiRequest.request<any>(HttpMethod.POST, url, settlementParam, customHeaders);
        fullscreenLoading.value = false;
        buLoading.value = false;
        ElMessage({
            message: '结算成功',
            type: 'success',
        });
    } catch (error) {
        console.log('request: /api/cart/pay failed, error message: ', error);
        fullscreenLoading.value = false;
        buLoading.value = false;
    }
};
</script>

<style scoped>
.buy-div {
    width: 80%;
}

.buy-div-col {
    text-align: right;
    line-height: 40px;
}

.buy-div-col-price {
    color: #FF4900;
}

.buy-div-col-button {
    width: 100px;
    font-size: 16px;
    padding: 10px 0;
}

.table-up {
    width: 60vw;
    min-width: 800px;
    margin: 10px auto;
}

.table-image {
    width: 100px;
    height: 100px;
    margin: 10px 15px 10px 0
}

.table-row-col-txt {
    padding: 10px 5px 0 15px;
    line-height: 24px;
    font-size: 14px;
    width: 100%;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    -webkit-user-select: none;
    /* 适用于Chrome、Safari等浏览器 */
    -moz-user-select: none;
    /* 适用于Firefox浏览器 */
    -ms-user-select: none;
    /* 适用于IE浏览器 */
    user-select: none;
    /* 标准语法，适用于现代浏览器 */
}

.text_desc {
    font-size: 12px;
    color: #C0C0C0;
}

.el-card-pagination {
    justify-content: flex-end;
    display: flex;
    width: 80%;
    margin: 10px 0 20px 0;
}

.table-row-col-img {
    display: flex;
    justify-content: flex-end;
    border-radius: 10px;
}

.table-row-col-info {
    border-radius: 10px;
}

.table-row-col-info:hover {
    box-shadow: 0 0 10px rgba(92, 175, 144, 0.5);
    border: 1px solid rgb(92, 175, 144);
}

.row-price {
    color: #FF4900;
}

body {
    margin: 0;
}
</style>